blob: bb75f5ac65020ff8884da5e40f868b5a07b41a52 [file] [log] [blame]
Jamie Hannaforded7f4532015-02-17 14:56:30 +01001package configurations
2
3import (
4 "errors"
5
6 "github.com/rackspace/gophercloud"
7 "github.com/rackspace/gophercloud/openstack/db/v1/instances"
8 "github.com/rackspace/gophercloud/pagination"
9)
10
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010011// List will list all of the available configurations.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010012func List(client *gophercloud.ServiceClient) pagination.Pager {
13 pageFn := func(r pagination.PageResult) pagination.Page {
14 return ConfigPage{pagination.SinglePageBase(r)}
15 }
16
17 return pagination.NewPager(client, baseURL(client), pageFn)
18}
19
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010020// CreateOptsBuilder is a top-level interface which renders a JSON map.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010021type CreateOptsBuilder interface {
22 ToConfigCreateMap() (map[string]interface{}, error)
23}
24
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010025// DatastoreOpts is the primary options struct for creating and modifying
26// how configuration resources are associated with datastores.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010027type DatastoreOpts struct {
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010028 // [OPTIONAL] The type of datastore. Defaults to "MySQL".
29 Type string
30
31 // [OPTIONAL] The specific version of a datastore. Defaults to "5.6".
Jamie Hannaforded7f4532015-02-17 14:56:30 +010032 Version string
33}
34
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010035// ToMap renders a JSON map for a datastore setting.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010036func (opts DatastoreOpts) ToMap() (map[string]string, error) {
37 datastore := map[string]string{}
38
39 if opts.Type != "" {
40 datastore["type"] = opts.Type
41 }
42
43 if opts.Version != "" {
44 datastore["version"] = opts.Version
45 }
46
47 return datastore, nil
48}
49
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010050// CreateOpts is the struct responsible for configuring new configurations.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010051type CreateOpts struct {
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010052 // [REQUIRED] The configuration group name
53 Name string
54
55 // [REQUIRED] A map of user-defined configuration settings that will define
56 // how each associated datastore works. Each key/value pair is specific to a
57 // datastore type.
58 Values map[string]interface{}
59
60 // [OPTIONAL] Associates the configuration group with a particular datastore.
61 Datastore *DatastoreOpts
62
63 // [OPTIONAL] A human-readable explanation for the group.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010064 Description string
Jamie Hannaforded7f4532015-02-17 14:56:30 +010065}
66
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010067// ToConfigCreateMap casts a CreateOpts struct into a JSON map.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010068func (opts CreateOpts) ToConfigCreateMap() (map[string]interface{}, error) {
69 if opts.Name == "" {
70 return nil, errors.New("Name is a required field")
71 }
72 if len(opts.Values) == 0 {
73 return nil, errors.New("Values must be a populated map")
74 }
75
76 config := map[string]interface{}{
77 "name": opts.Name,
78 "values": opts.Values,
79 }
80
81 if opts.Datastore != nil {
82 ds, err := opts.Datastore.ToMap()
83 if err != nil {
84 return config, err
85 }
86 config["datastore"] = ds
87 }
88
89 if opts.Description != "" {
90 config["description"] = opts.Description
91 }
92
93 return map[string]interface{}{"configuration": config}, nil
94}
95
Jamie Hannafordb0d267b2015-02-19 11:59:53 +010096// Create will create a new configuration group.
Jamie Hannaforded7f4532015-02-17 14:56:30 +010097func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
98 var res CreateResult
99
100 reqBody, err := opts.ToConfigCreateMap()
101 if err != nil {
102 res.Err = err
103 return res
104 }
105
106 _, res.Err = client.Request("POST", baseURL(client), gophercloud.RequestOpts{
Jamie Hannaford99eced52015-03-02 15:24:22 +0100107 OkCodes: []int{200},
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100108 JSONBody: &reqBody,
109 JSONResponse: &res.Body,
110 })
111
112 return res
113}
114
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100115// Get will retrieve the details for a specified configuration group.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100116func Get(client *gophercloud.ServiceClient, configID string) GetResult {
117 var res GetResult
118
119 _, res.Err = client.Request("GET", resourceURL(client, configID), gophercloud.RequestOpts{
120 OkCodes: []int{200},
121 JSONResponse: &res.Body,
122 })
123
124 return res
125}
126
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100127// UpdateOptsBuilder is the top-level interface for casting update options into
128// JSON maps.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100129type UpdateOptsBuilder interface {
130 ToConfigUpdateMap() (map[string]interface{}, error)
131}
132
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100133// UpdateOpts is the struct responsible for modifying existing configurations.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100134type UpdateOpts struct {
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100135 // [OPTIONAL] The configuration group name
136 Name string
137
138 // [OPTIONAL] A map of user-defined configuration settings that will define
139 // how each associated datastore works. Each key/value pair is specific to a
140 // datastore type.
141 Values map[string]interface{}
142
143 // [OPTIONAL] Associates the configuration group with a particular datastore.
144 Datastore *DatastoreOpts
145
146 // [OPTIONAL] A human-readable explanation for the group.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100147 Description string
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100148}
149
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100150// ToConfigUpdateMap will cast an UpdateOpts struct into a JSON map.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100151func (opts UpdateOpts) ToConfigUpdateMap() (map[string]interface{}, error) {
152 config := map[string]interface{}{}
153
154 if opts.Name != "" {
155 config["name"] = opts.Name
156 }
157
158 if opts.Description != "" {
159 config["description"] = opts.Description
160 }
161
162 if opts.Datastore != nil {
163 ds, err := opts.Datastore.ToMap()
164 if err != nil {
165 return config, err
166 }
167 config["datastore"] = ds
168 }
169
170 if len(opts.Values) > 0 {
171 config["values"] = opts.Values
172 }
173
174 return map[string]interface{}{"configuration": config}, nil
175}
176
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100177// Update will modify an existing configuration group by performing a merge
178// between new and existing values. If the key already exists, the new value
179// will overwrite. All other keys will remain unaffected.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100180func Update(client *gophercloud.ServiceClient, configID string, opts UpdateOptsBuilder) UpdateResult {
181 var res UpdateResult
182
183 reqBody, err := opts.ToConfigUpdateMap()
184 if err != nil {
185 res.Err = err
186 return res
187 }
188
189 _, res.Err = client.Request("PATCH", resourceURL(client, configID), gophercloud.RequestOpts{
190 OkCodes: []int{200},
191 JSONBody: &reqBody,
192 JSONResponse: &res.Body,
193 })
194
195 return res
196}
197
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100198// Replace will modify an existing configuration group by overwriting the
199// entire parameter group with the new values provided. Any existing keys not
200// included in UpdateOptsBuilder will be deleted.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100201func Replace(client *gophercloud.ServiceClient, configID string, opts UpdateOptsBuilder) ReplaceResult {
202 var res ReplaceResult
203
204 reqBody, err := opts.ToConfigUpdateMap()
205 if err != nil {
206 res.Err = err
207 return res
208 }
209
210 _, res.Err = client.Request("PUT", resourceURL(client, configID), gophercloud.RequestOpts{
211 OkCodes: []int{202},
212 JSONBody: &reqBody,
213 JSONResponse: &res.Body,
214 })
215
216 return res
217}
218
Jamie Hannaford99eced52015-03-02 15:24:22 +0100219// Delete will permanently delete a configuration group. Please note that
220// config groups cannot be deleted whilst still attached to running instances -
221// you must detach and then delete them.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100222func Delete(client *gophercloud.ServiceClient, configID string) DeleteResult {
223 var res DeleteResult
224
225 _, res.Err = client.Request("DELETE", resourceURL(client, configID), gophercloud.RequestOpts{
226 OkCodes: []int{202},
227 })
228
229 return res
230}
231
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100232// ListInstances will list all the instances associated with a particular
233// configuration group.
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100234func ListInstances(client *gophercloud.ServiceClient, configID string) pagination.Pager {
235 pageFn := func(r pagination.PageResult) pagination.Page {
236 return instances.InstancePage{pagination.LinkedPageBase{PageResult: r}}
237 }
Jamie Hannaforded7f4532015-02-17 14:56:30 +0100238 return pagination.NewPager(client, instancesURL(client, configID), pageFn)
239}
Jamie Hannaford23867bb2015-02-17 15:56:48 +0100240
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100241// ListDatastoreParams will list all the available and supported parameters
242// that can be used for a particular datastore ID and a particular version.
243// For example, if you are wondering how you can configure a MySQL 5.6 instance,
244// you can use this operation (you will need to retrieve the MySQL datastore ID
245// by using the datastores API).
Jamie Hannaford23867bb2015-02-17 15:56:48 +0100246func ListDatastoreParams(client *gophercloud.ServiceClient, datastoreID, versionID string) pagination.Pager {
247 pageFn := func(r pagination.PageResult) pagination.Page {
248 return ParamPage{pagination.SinglePageBase(r)}
249 }
250 return pagination.NewPager(client, listDSParamsURL(client, datastoreID, versionID), pageFn)
251}
252
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100253// GetDatastoreParam will retrieve information about a specific configuration
254// parameter. For example, you can use this operation to understand more about
255// "innodb_file_per_table" configuration param for MySQL datastores. You will
256// need the param's ID first, which can be attained by using the ListDatastoreParams
257// operation.
Jamie Hannaford23867bb2015-02-17 15:56:48 +0100258func GetDatastoreParam(client *gophercloud.ServiceClient, datastoreID, versionID, paramID string) ParamResult {
259 var res ParamResult
260
261 _, res.Err = client.Request("GET", getDSParamURL(client, datastoreID, versionID, paramID), gophercloud.RequestOpts{
262 OkCodes: []int{200},
263 JSONResponse: &res.Body,
264 })
265
266 return res
267}
268
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100269// ListGlobalParams is similar to ListDatastoreParams but does not require a
270// DatastoreID.
Jamie Hannaford23867bb2015-02-17 15:56:48 +0100271func ListGlobalParams(client *gophercloud.ServiceClient, versionID string) pagination.Pager {
272 pageFn := func(r pagination.PageResult) pagination.Page {
273 return ParamPage{pagination.SinglePageBase(r)}
274 }
275 return pagination.NewPager(client, listGlobalParamsURL(client, versionID), pageFn)
276}
277
Jamie Hannafordb0d267b2015-02-19 11:59:53 +0100278// GetGlobalParam is similar to GetDatastoreParam but does not require a
279// DatastoreID.
Jamie Hannaford23867bb2015-02-17 15:56:48 +0100280func GetGlobalParam(client *gophercloud.ServiceClient, versionID, paramID string) ParamResult {
281 var res ParamResult
282
283 _, res.Err = client.Request("GET", getGlobalParamURL(client, versionID, paramID), gophercloud.RequestOpts{
284 OkCodes: []int{200},
285 JSONResponse: &res.Body,
286 })
287
288 return res
289}