226 lines
7.1 KiB
Go
226 lines
7.1 KiB
Go
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
|
|
}
|