forked from hashicorp/terraform
-
Notifications
You must be signed in to change notification settings - Fork 2
/
resource_azure_sql_database_server_firewall_rule.go
225 lines (189 loc) · 7.07 KB
/
resource_azure_sql_database_server_firewall_rule.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
package azure
import (
"fmt"
"log"
"strings"
"github.com/Azure/azure-sdk-for-go/management/sql"
"github.com/hashicorp/terraform/helper/schema"
)
// resourceAzureSqlDatabaseServerFirewallRule returns the *schema.Resource
// associated to a firewall rule of a database server in Azure.
func resourceAzureSqlDatabaseServerFirewallRule() *schema.Resource {
return &schema.Resource{
Create: resourceAzureSqlDatabaseServerFirewallRuleCreate,
Read: resourceAzureSqlDatabaseServerFirewallRuleRead,
Update: resourceAzureSqlDatabaseServerFirewallRuleUpdate,
Delete: resourceAzureSqlDatabaseServerFirewallRuleDelete,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"database_server_names": &schema.Schema{
Type: schema.TypeSet,
Required: true,
ForceNew: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Set: schema.HashString,
},
"start_ip": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"end_ip": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
}
}
// resourceAzureSqlDatabaseServerFirewallRuleCreate does all the necessary API
// calls to create the SQL Database Server Firewall Rule on Azure.
func resourceAzureSqlDatabaseServerFirewallRuleCreate(d *schema.ResourceData, meta interface{}) error {
sqlClient := meta.(*Client).sqlClient
name := d.Get("name").(string)
params := sql.FirewallRuleCreateParams{
Name: name,
StartIPAddress: d.Get("start_ip").(string),
EndIPAddress: d.Get("end_ip").(string),
}
// loop over all the database servers and apply the firewall rule to each:
serverNames := d.Get("database_server_names").(*schema.Set).List()
for _, srv := range serverNames {
serverName := srv.(string)
log.Printf("[INFO] Sending Azure Database Server Firewall Rule %q creation request for Server %q.", name, serverName)
if err := sqlClient.CreateFirewallRule(serverName, params); err != nil {
return fmt.Errorf("Error creating Azure Database Server Firewall Rule %q for Server %q: %s", name, serverName, err)
}
}
d.SetId(name)
return nil
}
// resourceAzureSqlDatabaseServerFirewallRuleRead does all the necessary API
// calls to read the state of the SQL Database Server Firewall Rule on Azure.
func resourceAzureSqlDatabaseServerFirewallRuleRead(d *schema.ResourceData, meta interface{}) error {
sqlClient := meta.(*Client).sqlClient
name := d.Get("name").(string)
remaining := schema.NewSet(schema.HashString, nil)
// for each of our servers; check to see if the rule is still present:
var found bool
for _, srv := range d.Get("database_server_names").(*schema.Set).List() {
serverName := srv.(string)
log.Printf("[INFO] Sending Azure Database Server Firewall Rule list query for server %q.", serverName)
rules, err := sqlClient.ListFirewallRules(serverName)
if err != nil {
if strings.Contains(err.Error(), "does not exist") {
// it means that the database server this rule belonged to has
// been deleted in the meantime.
continue
} else {
return fmt.Errorf("Error getting Azure Firewall Rules for Database Server %q: %s", serverName, err)
}
}
// look for our rule:
for _, rule := range rules.FirewallRules {
if rule.Name == name {
found = true
remaining.Add(serverName)
break
}
}
}
// check to see if there is still any Database Server still having this rule:
if !found {
d.SetId("")
return nil
}
// else; update the list of Database Servers still having this rule:
d.Set("database_server_names", remaining)
return nil
}
// resourceAzureSqlDatabaseServerFirewallRuleUpdate does all the necessary API
// calls to update the state of the SQL Database Server Firewall Rule on Azure.
func resourceAzureSqlDatabaseServerFirewallRuleUpdate(d *schema.ResourceData, meta interface{}) error {
sqlClient := meta.(*Client).sqlClient
var found bool
name := d.Get("name").(string)
updateParams := sql.FirewallRuleUpdateParams{
Name: name,
StartIPAddress: d.Get("start_ip").(string),
EndIPAddress: d.Get("end_ip").(string),
}
// for each of the Database Servers our rules concerns; issue the update:
remaining := schema.NewSet(schema.HashString, nil)
for _, srv := range d.Get("database_server_names").(*schema.Set).List() {
serverName := srv.(string)
log.Printf("[INFO] Issuing Azure Database Server Firewall Rule list for Database Server %q: %s.", name, serverName)
rules, err := sqlClient.ListFirewallRules(serverName)
if err != nil {
if strings.Contains(err.Error(), "does not exist") {
// it means that the database server this rule belonged to has
// been deleted in the meantime.
continue
} else {
return fmt.Errorf("Error getting Azure Firewall Rules for Database Server %q: %s", serverName, err)
}
}
// look for our rule:
for _, rule := range rules.FirewallRules {
if rule.Name == name {
// take note of the fact that this Database Server still has
// this rule:
found = true
remaining.Add(serverName)
// go ahead and update the rule:
log.Printf("[INFO] Issuing update of Azure Database Server Firewall Rule %q in Server %q.", name, serverName)
if err := sqlClient.UpdateFirewallRule(serverName, name, updateParams); err != nil {
return fmt.Errorf("Error updating Azure Database Server Firewall Rule %q for Server %q: %s", name, serverName, err)
}
break
}
}
}
// check to see if the rule is still exists on any of the servers:
if !found {
d.SetId("")
return nil
}
// else; update the list with the remaining Servers:
d.Set("database_server_names", remaining)
return nil
}
// resourceAzureSqlDatabaseServerFirewallRuleDelete does all the necessary API
// calls to delete the SQL Database Server Firewall Rule on Azure.
func resourceAzureSqlDatabaseServerFirewallRuleDelete(d *schema.ResourceData, meta interface{}) error {
sqlClient := meta.(*Client).sqlClient
name := d.Get("name").(string)
for _, srv := range d.Get("database_server_names").(*schema.Set).List() {
serverName := srv.(string)
log.Printf("[INFO] Sending Azure Database Server Firewall Rule list query for Server %q.", serverName)
rules, err := sqlClient.ListFirewallRules(serverName)
if err != nil {
if strings.Contains(err.Error(), "does not exist") {
// it means that the database server this rule belonged to has
// been deleted in the meantime.
continue
} else {
return fmt.Errorf("Error getting Azure Firewall Rules for Database Server %q: %s", serverName, err)
}
}
// look for our rule:
for _, rule := range rules.FirewallRules {
if rule.Name == name {
// go ahead and delete the rule:
log.Printf("[INFO] Issuing deletion of Azure Database Server Firewall Rule %q in Server %q.", name, serverName)
if err := sqlClient.DeleteFirewallRule(serverName, name); err != nil {
if strings.Contains(err.Error(), "Cannot open server") {
break
}
return fmt.Errorf("Error deleting Azure Database Server Firewall Rule %q for Server %q: %s", name, serverName, err)
}
break
}
}
}
return nil
}