terraform-provider-greenhost/digitalocean/resource_digitalocean_datab...

180 lines
4.7 KiB
Go

package digitalocean
import (
"context"
"fmt"
"log"
"time"
"github.com/digitalocean/godo"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func resourceDigitalOceanDatabaseFirewall() *schema.Resource {
return &schema.Resource{
Create: resourceDigitalOceanDatabaseFirewallCreate,
Read: resourceDigitalOceanDatabaseFirewallRead,
Update: resourceDigitalOceanDatabaseFirewallUpdate,
Delete: resourceDigitalOceanDatabaseFirewallDelete,
Importer: &schema.ResourceImporter{
State: resourceDigitalOceanDatabaseFirewallImport,
},
Schema: map[string]*schema.Schema{
"cluster_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.NoZeroValues,
},
"rule": {
Type: schema.TypeSet,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
"ip_addr",
"droplet",
"k8s",
"tag",
}, false),
},
"value": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.NoZeroValues,
},
"uuid": {
Type: schema.TypeString,
Computed: true,
},
"created_at": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}
func resourceDigitalOceanDatabaseFirewallCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*CombinedConfig).godoClient()
clusterID := d.Get("cluster_id").(string)
rules := buildDatabaseFirewallRequest(d.Get("rule").(*schema.Set).List())
_, err := client.Databases.UpdateFirewallRules(context.TODO(), clusterID, &rules)
if err != nil {
return fmt.Errorf("Error creating DatabaseFirewall: %s", err)
}
d.SetId(resource.PrefixedUniqueId(clusterID + "-"))
return resourceDigitalOceanDatabaseFirewallRead(d, meta)
}
func resourceDigitalOceanDatabaseFirewallRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*CombinedConfig).godoClient()
clusterID := d.Get("cluster_id").(string)
rules, _, err := client.Databases.GetFirewallRules(context.TODO(), clusterID)
if err != nil {
return fmt.Errorf("Error retrieving DatabaseFirewall: %s", err)
}
return d.Set("rule", flattenDatabaseFirewallRules(rules))
}
func resourceDigitalOceanDatabaseFirewallUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*CombinedConfig).godoClient()
clusterID := d.Get("cluster_id").(string)
rules := buildDatabaseFirewallRequest(d.Get("rule").(*schema.Set).List())
_, err := client.Databases.UpdateFirewallRules(context.TODO(), clusterID, &rules)
if err != nil {
return fmt.Errorf("Error updating DatabaseFirewall: %s", err)
}
return resourceDigitalOceanDatabaseFirewallRead(d, meta)
}
func resourceDigitalOceanDatabaseFirewallDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*CombinedConfig).godoClient()
clusterID := d.Get("cluster_id").(string)
log.Printf("[INFO] Deleting DatabaseFirewall: %s", d.Id())
req := godo.DatabaseUpdateFirewallRulesRequest{
Rules: []*godo.DatabaseFirewallRule{},
}
_, err := client.Databases.UpdateFirewallRules(context.TODO(), clusterID, &req)
if err != nil {
return fmt.Errorf("Error deleting DatabaseFirewall: %s", err)
}
d.SetId("")
return nil
}
func resourceDigitalOceanDatabaseFirewallImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
clusterID := d.Id()
d.Set("cluster_id", clusterID)
d.SetId(resource.PrefixedUniqueId(clusterID + "-"))
return []*schema.ResourceData{d}, nil
}
func buildDatabaseFirewallRequest(rules []interface{}) godo.DatabaseUpdateFirewallRulesRequest {
expandedRules := make([]*godo.DatabaseFirewallRule, 0, len(rules))
for _, rawRule := range rules {
rule := rawRule.(map[string]interface{})
r := godo.DatabaseFirewallRule{
Type: rule["type"].(string),
Value: rule["value"].(string),
}
if rule["uuid"].(string) != "" {
r.UUID = rule["uuid"].(string)
}
expandedRules = append(expandedRules, &r)
}
return godo.DatabaseUpdateFirewallRulesRequest{
Rules: expandedRules,
}
}
func flattenDatabaseFirewallRules(rules []godo.DatabaseFirewallRule) []interface{} {
if rules == nil {
return nil
}
flattenedRules := make([]interface{}, len(rules))
for i, rule := range rules {
rawRule := map[string]interface{}{
"uuid": rule.UUID,
"type": rule.Type,
"value": rule.Value,
"created_at": rule.CreatedAt.Format(time.RFC3339),
}
flattenedRules[i] = rawRule
}
return flattenedRules
}