forked from hashicorp/terraform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
resource_azure_sql_database_service.go
234 lines (203 loc) · 7.25 KB
/
resource_azure_sql_database_service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package azure
import (
"fmt"
"log"
"strconv"
"strings"
"github.com/Azure/azure-sdk-for-go/management/sql"
"github.com/hashicorp/terraform/helper/schema"
)
// resourceAzureSqlDatabaseService returns the *schema.Resource
// associated to an SQL Database Service on Azure.
func resourceAzureSqlDatabaseService() *schema.Resource {
return &schema.Resource{
Create: resourceAzureSqlDatabaseServiceCreate,
Read: resourceAzureSqlDatabaseServiceRead,
Update: resourceAzureSqlDatabaseServiceUpdate,
Exists: resourceAzureSqlDatabaseServiceExists,
Delete: resourceAzureSqlDatabaseServiceDelete,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"database_server_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"collation": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"edition": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"max_size_bytes": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"service_level_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}
// resourceAzureSqlDatabaseServiceCreate does all the necessary API calls to
// create an SQL Database Service on Azure.
func resourceAzureSqlDatabaseServiceCreate(d *schema.ResourceData, meta interface{}) error {
sqlClient := meta.(*Client).sqlClient
log.Println("[INFO] Creating Azure SQL Database service creation request.")
name := d.Get("name").(string)
serverName := d.Get("database_server_name").(string)
params := sql.DatabaseCreateParams{
Name: name,
Edition: d.Get("edition").(string),
CollationName: d.Get("collation").(string),
ServiceObjectiveID: d.Get("service_level_id").(string),
}
if maxSize, ok := d.GetOk("max_size_bytes"); ok {
val, err := strconv.ParseInt(maxSize.(string), 10, 64)
if err != nil {
return fmt.Errorf("Provided max_size_bytes is not an integer: %s", err)
}
params.MaxSizeBytes = val
}
log.Println("[INFO] Sending SQL Database Service creation request to Azure.")
err := sqlClient.CreateDatabase(serverName, params)
if err != nil {
return fmt.Errorf("Error issuing Azure SQL Database Service creation: %s", err)
}
log.Println("[INFO] Beginning wait for Azure SQL Database Service creation.")
err = sqlClient.WaitForDatabaseCreation(serverName, name, nil)
if err != nil {
return fmt.Errorf("Error whilst waiting for Azure SQL Database Service creation: %s", err)
}
d.SetId(name)
return resourceAzureSqlDatabaseServiceRead(d, meta)
}
// resourceAzureSqlDatabaseServiceRead does all the necessary API calls to
// read the state of the SQL Database Service off Azure.
func resourceAzureSqlDatabaseServiceRead(d *schema.ResourceData, meta interface{}) error {
sqlClient := meta.(*Client).sqlClient
log.Println("[INFO] Issuing Azure SQL Database Services list operation.")
serverName := d.Get("database_server_name").(string)
dbs, err := sqlClient.ListDatabases(serverName)
if err != nil {
return fmt.Errorf("Error whilst listing Database Services off Azure: %s", err)
}
// search for our database:
var found bool
name := d.Get("name").(string)
for _, db := range dbs.ServiceResources {
if db.Name == name {
found = true
d.Set("edition", db.Edition)
d.Set("collation", db.CollationName)
d.Set("max_size_bytes", strconv.FormatInt(db.MaxSizeBytes, 10))
d.Set("service_level_id", db.ServiceObjectiveID)
break
}
}
// if not found; we must untrack the resource:
if !found {
d.SetId("")
}
return nil
}
// resourceAzureSqlDatabaseServiceUpdate does all the necessary API calls to
// update the state of the SQL Database Service off Azure.
func resourceAzureSqlDatabaseServiceUpdate(d *schema.ResourceData, meta interface{}) error {
azureClient := meta.(*Client)
mgmtClient := azureClient.mgmtClient
sqlClient := azureClient.sqlClient
serverName := d.Get("database_server_name").(string)
// changes to the name must occur separately from changes to the attributes:
if d.HasChange("name") {
oldv, newv := d.GetChange("name")
// issue the update request:
log.Println("[INFO] Issuing Azure Database Service name change.")
reqID, err := sqlClient.UpdateDatabase(serverName, oldv.(string),
sql.ServiceResourceUpdateParams{
Name: newv.(string),
})
// wait for the update to occur:
log.Println("[INFO] Waiting for Azure SQL Database Service name change.")
err = mgmtClient.WaitForOperation(reqID, nil)
if err != nil {
return fmt.Errorf("Error waiting for Azure SQL Database Service name update: %s", err)
}
// set the new name as the ID:
d.SetId(newv.(string))
}
name := d.Get("name").(string)
cedition := d.HasChange("edition")
cmaxsize := d.HasChange("max_size_bytes")
clevel := d.HasChange("service_level_id")
if cedition || cmaxsize || clevel {
updateParams := sql.ServiceResourceUpdateParams{
// we still have to stick the name in here for good measure:
Name: name,
}
// build the update request:
if cedition {
updateParams.Edition = d.Get("edition").(string)
}
if maxSize, ok := d.GetOk("max_size_bytes"); cmaxsize && ok && maxSize.(string) != "" {
val, err := strconv.ParseInt(maxSize.(string), 10, 64)
if err != nil {
return fmt.Errorf("Provided max_size_bytes is not an integer: %s", err)
}
updateParams.MaxSizeBytes = val
}
if clevel {
updateParams.ServiceObjectiveID = d.Get("service_level_id").(string)
}
// issue the update:
log.Println("[INFO] Issuing Azure Database Service parameter update.")
reqID, err := sqlClient.UpdateDatabase(serverName, name, updateParams)
if err != nil {
return fmt.Errorf("Failed issuing Azure SQL Service parameter update: %s", err)
}
log.Println("[INFO] Waiting for Azure SQL Database Service parameter update.")
err = mgmtClient.WaitForOperation(reqID, nil)
if err != nil {
return fmt.Errorf("Error waiting for Azure SQL Database Service parameter update: %s", err)
}
}
return nil
}
// resourceAzureSqlDatabaseServiceExists does all the necessary API calls to
// check for the existence of the SQL Database Service off Azure.
func resourceAzureSqlDatabaseServiceExists(d *schema.ResourceData, meta interface{}) (bool, error) {
sqlClient := meta.(*Client).sqlClient
log.Println("[INFO] Issuing Azure SQL Database Service get request.")
name := d.Get("name").(string)
serverName := d.Get("database_server_name").(string)
_, err := sqlClient.GetDatabase(serverName, name)
if err != nil {
if strings.Contains(err.Error(), "does not exist") {
d.SetId("")
return false, nil
} else {
return false, fmt.Errorf("Error whilst getting Azure SQL Database Service info: %s", err)
}
}
return true, nil
}
// resourceAzureSqlDatabaseServiceDelete does all the necessary API calls to
// delete the SQL Database Service off Azure.
func resourceAzureSqlDatabaseServiceDelete(d *schema.ResourceData, meta interface{}) error {
sqlClient := meta.(*Client).sqlClient
log.Println("[INFO] Issuing Azure SQL Database deletion request.")
name := d.Get("name").(string)
serverName := d.Get("database_server_name").(string)
return sqlClient.DeleteDatabase(serverName, name)
}